package com.atguigu.tingshu.payment.service.impl;

import cn.hutool.core.lang.Assert;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.payment.PaymentInfo;
import com.atguigu.tingshu.order.client.OrderFeignClient;
import com.atguigu.tingshu.payment.config.WxPayV3Config;
import com.atguigu.tingshu.payment.service.PaymentInfoService;
import com.atguigu.tingshu.payment.service.WxPayService;
import com.atguigu.tingshu.payment.util.PayUtil;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

	@Autowired
	private PaymentInfoService paymentInfoService;
	@Autowired
	private WxPayV3Config wxPayV3Config;
	@Autowired
	RSAAutoCertificateConfig rsaAutoCertificateConfig;
	@Autowired
	private OrderFeignClient orderFeignClient;
	@Autowired
	private UserFeignClient userFeignClient;

	@Override
	public Map<String, String> createJsapi(String paymentType, String orderNo) {
		OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderNo).getData();
		Assert.notNull(orderInfo,"无法查询到该订单");
		Long userId = AuthContextHolder.getUserId();
		UserInfoVo userInfoVo = userFeignClient.getUserVoById(userId).getData();
		Assert.notNull(userInfoVo,"无法查询该用户数据");
		String description = "测试";
		if (SystemConstant.PAYMENT_TYPE_ORDER.equals(paymentType)){
			description = "订单支付";
		}

		// 构建service
		JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
// 跟之前下单示例一样，填充预下单参数
		PrepayRequest request = new PrepayRequest();

		Amount amount = new Amount();
		amount.setTotal(1);
		request.setAmount(amount);
		request.setMchid(wxPayV3Config.getMerchantId());
		request.setAppid(wxPayV3Config.getAppid());
		request.setDescription(description);
		Payer payer = new Payer();
		payer.setOpenid("odo3j4ujPBRopdATZnxKZ3HDOLAc");
		request.setPayer(payer);
		request.setNotifyUrl(wxPayV3Config.getNotifyUrl());
		request.setOutTradeNo(orderNo);

//		// 调用下单方法，得到应答
		PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);

//		PrepayResponse response = service.prepay(request);
//		String codeUrl = response.getCodeUrl();

		HashMap<String, String> map = new HashMap<>();
		map.put("timeStamp",response.getTimeStamp());
		map.put("package",response.getPackageVal());
		map.put("paySign",response.getPaySign());
		map.put("signType",response.getSignType());
		map.put("nonceStr",response.getNonceStr());
		return map;
	}

	@Override
	public Boolean queryPayStatus(String orderNo) {
		JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();

		QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
		request.setOutTradeNo(orderNo);



		request.setMchid(wxPayV3Config.getMerchantId());

		Transaction transaction = service.queryOrderByOutTradeNo(request);
		Transaction.TradeStateEnum tradeState = transaction.getTradeState();

		if (tradeState.equals(Transaction.TradeStateEnum.SUCCESS)){
			return true;
		}
		return false;
	}

	@Override

	public Map<String, String> paySuccessNotify(HttpServletRequest request) {
		//封装应答对象
		Map<String,String> resultMap=new HashMap<>();
		resultMap.put("code","500");
		resultMap.put("message","失败");

		Transaction transaction = null;
		try {
			//获取请求头信息
			String wechatSignature = request.getHeader("Wechatpay-Signature");
			String wechatPaySerial = request.getHeader("Wechatpay-Serial");
			String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
			String wechatTimestamp = request.getHeader("Wechatpay-Timestamp");

			//处理请求体
			String requestBody = PayUtil.readData(request);

			// 构造 RequestParam
			RequestParam requestParam = new RequestParam.Builder()
					.serialNumber(wechatPaySerial)
					.nonce(wechatpayNonce)
					.signature(wechatSignature)
					.timestamp(wechatTimestamp)
					.body(requestBody)
					.build();

			// 初始化 NotificationParser
			NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
			//解析回调信息
			transaction = parser.parse(requestParam, Transaction.class);
		} catch (Exception e) {
			return resultMap;

		}
		//判断
		if(transaction!=null){
			Transaction.TradeStateEnum tradeState = transaction.getTradeState();
			//判断
			if(Transaction.TradeStateEnum.SUCCESS.equals(tradeState)){

				//对账付款记录
				Integer amount = transaction.getAmount().getTotal();
				//获取订单号
				String outTradeNo = transaction.getOutTradeNo();
				//查询付款记录
				PaymentInfo paymentInfo= paymentInfoService.getPaymentInfoByOutradeNo(outTradeNo);
				//校验
//                if(paymentInfo.getAmount().intValue()==amount.intValue()){
				if(1==amount.intValue()){

					try {
						//更新付款记录
						paymentInfoService.updatePaymentInfo(transaction);

						// 处理成功，返回 200 OK 状态码
						resultMap.put("code","200");
						resultMap.put("message","成功");
						return resultMap;
					} catch (Exception e) {
						throw new RuntimeException(e);
					}


				}

			}


		}




		return resultMap;
	}
}
